<?php

namespace App\Utils;

use App\Cache\TokenCache;
use App\Exception\BusinessException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Utils\ApplicationContext;

class WxTools
{
    /**
     * @param string $appid
     * @param string $secret
     * @param string $code
     * @return array
     * @throws GuzzleException
     */
    public static function code2session(string $appid, string $secret, string $code): array
    {
        $http = self::getHttp();
        $res = $http->get('https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid
            . '&secret=' . $secret
            . '&js_code=' . $code
            . '&grant_type=authorization_code');;
        if (($res->getStatusCode() === 200)
            && ($resClass = json_decode($res->getBody()->getContents()))
            && $resClass->session_key
            && $resClass->openid) {
            return [$resClass->openid, $resClass->session_key];
        } else {
            throw new BusinessException($res->getBody()->getContents());
        }
    }

    /**
     * @param string $appid
     * @param string $secret
     * @param string $code
     * @return array
     * @throws GuzzleException
     */
    public static function getPhoneByCode(string $appid, string $secret, string $code): array
    {
        $token = self::getToken($appid, $secret);
        $container = ApplicationContext::getContainer();
        $http = (new ClientFactory($container))->create();
        $options = ['header' => ['Content-type: application/json'], 'body' => json_encode(['code' => $code])];
        $res = $http->post('https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $token . '&', $options);
        $resa = $res->getBody()->getContents();
        if (
            ($res->getStatusCode() === 200)
            && ($resClass = json_decode($resa, true))
            && ($resClass['errcode'] == 0)
            && $resClass['phone_info']) {
            return $resClass['phone_info'];
        } else {
            throw new BusinessException;
        }
    }

    public static function getPhone(string $encryptedData, string $iv, string $sessionKey)
    {
//        $pc = new WxBizDataCrypt($this->wxAppId, $sessionKey);
//        $data = '';
//        $errCode = $pc->decryptData($encryptedData, $iv, $data);
//        if ($errCode === 0) {
//            return json_decode($data, true);
//        } else {
//            throw new BusinessException;
//        }
    }

    /**
     * @throws GuzzleException
     */
    protected static function getToken(string $appid, string $secret): string
    {
        $tokeCache = new TokenCache();
        if ($tokeCache->has('')) {
            return $tokeCache->get('');
        } else {
            $http = self::getHttp();
            $res = $http->get('https://api.weixin.qq.com/cgi-bin/token?appid=' . $appid
                . '&secret=' . $secret
                . '&grant_type=client_credential');
            if (($res->getStatusCode() === 200)
                && ($resClass = json_decode($res->getBody()->getContents()))
                && $resClass->access_token
                && $resClass->expires_in) {
                $tokeCache->set('', $resClass->access_token, $resClass->expires_in - 60);
                return $resClass->access_token;
            } else {
                throw new BusinessException;
            }
        }
    }

    public static function getHttp(): Client
    {
        $container = ApplicationContext::getContainer();
        return (new ClientFactory($container))->create();
    }
}